<?php


namespace app\api\model;


use app\common\library\IDMan;
use app\common\model\BaseModel;
use common;
use ApiOper;

class BikeRepairModel extends BaseModel
{
    protected $name = 'bike_repair_order';

    var $paramlist = [
        'id' => 'string',
        'city_id' => 'string',
        'bike_id' => 'string',
        'bike_sn' => 'string',
        'bike_model' => 'string',
        'report_fault_types' => 'array',
        'report_fault_descs' => 'array',
        'actual_fault_types' => 'array',
        'actual_fault_subtypes' => 'array',
        'actual_fault_descs' => 'array',
        'order_state' => 'int',
        'is_wheel_locked' => 'int',
        'is_under_volt' => 'int',
        'is_battery_locked' => 'int',
        'is_acc_on' => 'int',
        'battery_capacity' => 'int',
        'battery_level' => 'int',
        'battery_volt' => 'int',
        'health_state' => 'int',
        'coordinate' => 'array',
        'address' => 'string',
        'recaller_id' => 'string',
        'recaller_name' => 'string',
        'recall_time' => 'string',
        'repairer_name' => 'string',
        'repairer_id' => 'string',
        'repair_time' => 'string',
        'creator_id' => 'string',
        'creator_name' => 'string',
        'create_time' => 'string',
        'is_deleted' => 'string',
        'reporter_type' => 'int',
        'warehouse_id' => 'string',
        'warehouse_name' => 'string',
        'repair_remark' => 'string',
        'report_remark' => 'string',
    ];


    function add($city_id, $bike_id, $fault_types, $fault_desc)
    {
        $oper_info = ApiOper::instance()->userinfo();
        $bike_info = BikeModel::instance()->get_info_by_id($bike_id);
        if (empty($bike_info)) {
            $this->throw_myexception(ERROR_QUERY_INFO, "get order info error!");
        }
        if ($bike_info['health_state'] != 0) {
            $this->throw_myexception(X_ERROR, "车辆已经报修！");
        }

        $info = [
            'id' => IDMan::city_order_id($city_id),
            'city_id' => $city_id,
            'bike_id' => $bike_id,
            'bike_sn' => $bike_info['sn'],
            'bike_model' => $bike_info['model'],
            'report_fault_types' => $fault_types,
            'report_fault_descs' => $fault_desc,
            'order_state' => BIKE_REPAIR_STATE_REPORT,
            'reporter_type' => $oper_info['user_type'],
        ];


        ApiOper::instance()->append_creater_info($info);

        if (!empty($bike_info)) {
            $info['health_state'] = $bike_info['health_state'];
            $info['is_wheel_locked'] = $bike_info['is_wheel_locked'];
            $info['battery_level'] = $bike_info['battery_level'];
            $info['battery_capacity'] = $bike_info['battery_capacity'];
            $info['battery_volt'] = $bike_info['battery_volt'];
            $info['is_acc_on'] = $bike_info['is_acc_on'];
            $info['is_battery_locked'] = $bike_info['is_battery_locked'];
            $info['is_under_volt'] = $bike_info['is_under_volt'];
            $info['coordinate'] = $bike_info['coordinate'];
            $info['address'] = $bike_info['address'];
        }

        self::create($info);

        (new BikeMgr())->set_health_state($city_id, $bike_id, 1, $fault_desc);
        return $info;
    }

    function query_info($city_id, $order_id)
    {
        $sfs = array_keys($this->paramlist);
        $beans = [
            'city_id'=>$city_id,
            'id'=>$order_id,
        ];


        return $this->where($beans)->field($sfs)->find();
    }

    function recall($order_info, $warehouse_id, $warehouse_name)
    {
        $city_id = $order_info['city_id'];

        if ($order_info['order_state'] != BIKE_REPAIR_STATE_REPORT) {
            $this->throw_myexception(ERROR_STATE_DISMATCH, "order state = {$order_info['order_state']}");
        }

        $oper_info = ApiOper::instance()->userinfo();
        if (empty($order_info)) {
            $this->throw_myexception(ERROR_QUERY_INFO, "get info error");
        }
        if ($order_info['order_state'] != BIKE_REPAIR_STATE_REPORT) {
            $this->throw_myexception(ERROR_STATE_DISMATCH, "order state ! ");
        }

        $data = [
            'order_state' => BIKE_REPAIR_STATE_WH_IN,
            'warehouse_id' => $warehouse_id,
            'warehouse_name' => $warehouse_name,
            'recaller_id' => $oper_info['id'],
            'recaller_name' => $oper_info['name'],
            'recall_time' => date('Y-m-d H:i:s'),
        ];

        $where = [
            'city_id' => $city_id,
            'id' => $order_info['id'],
        ];
        self::update( $data, $where);

        (new BikeMgr())->recall($city_id, $order_info['bike_id'], $warehouse_id, $warehouse_name);
    }

    function repaire($order_info, $fault_types, $fault_subtypes, $fault_desc)
    {
        if ($order_info['order_state'] != BIKE_REPAIR_STATE_WH_IN && $order_info['order_state'] != BIKE_REPAIR_STATE_REPORT) {
            $this->throw_myexception(ERROR_STATE_DISMATCH, "order_state = {$order_info['order_state']}");
        }

        $oper_info = ApiOper::instance()->userinfo();
        if (empty($order_info)) {
            $this->throw_myexception(ERROR_QUERY_INFO, "get info error");
        }

        if ($order_info['order_state'] != BIKE_REPAIR_STATE_REPORT && $order_info['order_state'] != BIKE_REPAIR_STATE_WH_IN) {
            $this->throw_myexception(ERROR_STATE_DISMATCH, "order state ! ");
        }

        $data = [
            'order_state' => BIKE_REPAIR_STATE_FINISH,
            'actual_fault_types' => $fault_types,
            'actual_fault_descs' => $fault_desc,
            'actual_fault_subtypes' => $fault_subtypes,
            'repairer_id' => $oper_info['id'],
            'repairer_name' => $oper_info['name'],
            'repair_time' => date('Y-m-d H:i:s'),
        ];

        $where = [
            'city_id' => $order_info['city_id'],
            'id' => $order_info['id'],
        ];

        self::update($data, $where);

        (new BikeMgr())->set_health_state($order_info['city_id'], $order_info['bike_id'], 0, NULL);
    }

    function query_list($city_id, $condition, $pos, $limit)
    {
        $sfs = array_keys($this->paramlist);
        $st = "city_id = ? ";
        $beans = [$city_id];
        if (isset($condition['id'])) {
            $st = $st . " and bike_id = ?";
            $beans[] = $condition['id'];
        }
        if (isset($condition['order_state'])) {
            $st = $st . " and order_state = ?";
            $beans[] = $condition['order_state'];
        }

        if (isset($condition['is_order_finished'])) {
            if ($condition['is_order_finished']) {
                $st = $st . " and order_state = ?";
                $beans[] = BIKE_REPAIR_STATE_FINISH;
            } else {
                $st = $st . " and order_state < ?";
                $beans[] = BIKE_REPAIR_STATE_FINISH;
            }
        }

        if (isset($condition['order_state_in'])) {
            $in = implode(',', $condition['order_state_in']);
            $st = $st . " and order_state in ({$in})";
        }

        if (isset($condition['time_interval_type']) && in_array($condition['time_interval_type'], [1, 2,3])) {
            if ($condition['time_interval_type'] == 1) {
                if (isset($condition['start_time'])) {
                    $st = $st . " and create_time >= ? ";
                    $beans[] = $condition['start_time'];
                }
                if (isset($condition['end_time'])) {
                    $st = $st . " and create_time <= ? ";
                    $beans[] = $condition['end_time'];
                }
            } else if ($condition['time_interval_type'] == 2) {
                if (isset($condition['start_time'])) {
                    $st = $st . " and recall_time >= ? ";
                    $beans[] = $condition['start_time'];
                }
                if (isset($condition['end_time'])) {
                    $st = $st . " and recall_time <= ? ";
                    $beans[] = $condition['end_time'];
                }
            } else if ($condition['time_interval_type'] == 3) {
                if (isset($condition['start_time'])) {
                    $st = $st . " and repair_time >= ? ";
                    $beans[] = $condition['start_time'];
                }
                if (isset($condition['end_time'])) {
                    $st = $st . " and repair_time <= ? ";
                    $beans[] = $condition['end_time'];
                }
            }
        }

        if (isset($condition['is_recalled'])) {
            if ($condition['is_recalled']) {
                $st = $st . " and warehouse_id is not null";
            } else {
                $st = $st . " and warehouse_id is  null";
            }
        }
        if (isset($condition['report_fault_type'])) {
            $st = $st . " and json_contains(report_fault_types, ?, '$')";
            $beans[] = strval($condition['report_fault_type']);
        }

        if (isset($condition['actual_fault_type'])) {
            $st = $st . " and json_contains(actual_fault_types, ?, '$')";
            $beans[] = strval($condition['actual_fault_type']);
        }


        if (isset($condition['bike_model'])) {
            $st = $st . " and bike_model = ?";
            $beans[] = $condition['bike_model'];
        }
        if (isset($condition['warehouse_id'])) {
            $st = $st . " and warehouse_id = ?";
            $beans[] = $condition['warehouse_id'];
        }
        if (isset($condition['duration_interval'])) {
            $intv = explode(',', $condition['duration_interval']);
            if ($intv && count($intv) == 2) {
                $ds = intval($intv[0]);
                $de = intval($intv[1]);
                $start_time_low = date('Y-m-d H:i:s', time() - $de);
                $start_time_up = date('Y-m-d H:i:s', time() - $ds);
                $st = $st . " and ("
                    . "(duration is not null and duration  >= ? and duration <= ? )"
                    . " or (duration is null and  create_time >= ? and create_time <= ?)"
                    . ")";
                $beans[] = intval($ds);
                $beans[] = intval($de);
                $beans[] = $start_time_low;
                $beans[] = $start_time_up;
            }
        }

        if (isset($condition['bike_id'])) {
            $st = $st . " and bike_id = ?";
            $beans[] = $condition['bike_id'];
        }
        if (isset($condition['bike_sn'])) {
            $st = $st . " and bike_sn = ?";
            $beans[] = $condition['bike_sn'];
        }

        if (isset($condition['user_id'])) {
            //$st = $st . " and user_id = ?";
            //$beans[] = $condition['user_id'];
        }

        //$st = $st . " order by create_time desc limit $pos, $limit";


        $rows = $this->where($st,$beans)->field($sfs)->order('create_time','desc')->limit($pos,$limit)->select();
        if ($rows->isEmpty()) {
            return [];
        }
        $l = [];
        foreach ($rows as $row) {
            $l[] = common::sql_row($this->paramlist, $row);
        }
        return $l;
    }


    //分析
    function analyze($city_id,$condition){
        $condition['order_state'] = 100;
        $condition['time_interval_type'] = 3;

        $list = $this->query_list($city_id,$condition,0,5000);

        $repair_list =[];

        if (is_array($list)){
            foreach ($list as $val){
                if (!isset($repair_list[$val['repairer_id']])){
                    $repair_list[$val['repairer_id']] = 1;
                }
                else
                    $repair_list[$val['repairer_id']]++;
            }

        }

        return $repair_list;
    }
}